home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 January / EnigmA AMIGA RUN 33 (1999)(G.R. Edizioni)(IT)[!][issue 1999-01].iso / earcd / apus / boothack / old / bh980723.lha / bh980723 / bootstrap.c < prev    next >
C/C++ Source or Header  |  1980-01-14  |  9KB  |  349 lines

  1. /*
  2. ** linux/arch/m68k/boot/amiga/bootstrap.c -- This program loads the Linux/m68k
  3. **                         kernel into an Amiga and launches
  4. **                         it.
  5. **
  6. ** Copyright 1993,1994 by Hamish Macdonald, Greg Harp
  7. **
  8. ** Modified 11-May-94 by Geert Uytterhoeven
  9. **            (Geert.Uytterhoeven@cs.kuleuven.ac.be)
  10. **     - A3640 MapROM check
  11. ** Modified 31-May-94 by Geert Uytterhoeven
  12. **     - Memory thrash problem solved
  13. ** Modified 07-March-95 by Geert Uytterhoeven
  14. **     - Memory block sizes are rounded to a multiple of 256K instead of 1M
  15. **     This _requires_ >0.9pl5 to work!
  16. **     (unless all block sizes are multiples of 1M :-)
  17. ** Modified 11-July-95 by Andreas Schwab
  18. **     - Support for ELF kernel (untested!)
  19. ** Modified 10-Jan-96 by Geert Uytterhoeven
  20. **     - The real Linux/m68k boot code moved to linuxboot.[ch]
  21. ** Modified 9-Sep-96 by Geert Uytterhoeven
  22. **     - Rewritten option parsing
  23. **     - New parameter passing to linuxboot() (linuxboot_args)
  24. ** Modified 6-Oct-96 by Geert Uytterhoeven
  25. **     - Updated for the new boot information structure
  26. ** Modified 26-Feb-98 by Jesper Skov
  27. **     - Added support for booting APUS systems.
  28. **
  29. ** This file is subject to the terms and conditions of the GNU General Public
  30. ** License.  See the file COPYING in the main directory of this archive
  31. ** for more details.
  32. **
  33. */
  34.  
  35. #include <stddef.h>
  36. #include <stdlib.h>
  37. #include <stdio.h>
  38. #include <stdarg.h>
  39. #include <string.h>
  40. #include <sys/file.h>
  41. #include <sys/types.h>
  42. #include <unistd.h>
  43.  
  44. /* required Linux/m68k include files */
  45. #include <linux/a.out.h>
  46. #include <linux/elf.h>
  47. #include <asm/amigahw.h>
  48. #include <asm/page.h>
  49.  
  50. /* Amiga bootstrap include files */
  51. #include "linuxboot.h"
  52. #include "bootstrap.h"
  53.  
  54.  
  55. /* Library Bases */
  56. long __oslibversion = 36;
  57. extern const struct ExecBase *SysBase;
  58.  
  59. static const char *memfile_name = NULL;
  60.  
  61. static int model = AMI_UNKNOWN;
  62.  
  63. static const char *ProgramName;
  64.  
  65. struct linuxboot_args args;
  66.  
  67.  
  68.     /*
  69.      *  Function Prototypes
  70.      */
  71.  
  72. static void Usage(void) __attribute__ ((noreturn));
  73. int main(int argc, char *argv[]);
  74. static void Puts(const char *str);
  75. static long GetChar(void);
  76. static void PutChar(char c);
  77. static void Printf(const char *fmt, ...);
  78. static int Open(const char *path);
  79. static int Seek(int fd, int offset);
  80. static int Read(int fd, char *buf, int count);
  81. static void Close(int fd);
  82. static int FileSize(const char *path);
  83. static void Sleep(u_long micros);
  84.  
  85.  
  86. static void Usage(void)
  87. {
  88.     fprintf(stderr,
  89.     "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n"
  90.     "Usage: %s [options] [kernel command line]\n\n"
  91.     "Basic options:\n"
  92.     "    -h, --help           Display this usage information\n"
  93.     "    -k, --kernel file    Use kernel image `file' (default is `vmlinux')\n"
  94.     "    -r, --ramdisk file   Use ramdisk image `file'\n"
  95.     "Advanced options:\n"
  96.     "    -d, --debug          Enable debug mode\n"
  97.     "    -b, --baud speed     Set the serial port speed (default is 9600)\n"
  98.     "    -m, --memfile file   Use memory file `file'\n"
  99.     "    -v, --keep-video     Don't reset the video mode\n"
  100.     "    -t, --model id       Set the Amiga model to `id'\n"
  101.     "    -p, --processor cfm  Set the processor type to `cfm\n",
  102.     "        --apus           PPC boot on PowerUp\n\n",
  103.     ProgramName);
  104.     exit(EXIT_FAILURE);
  105. }
  106.  
  107. struct PPCLibBase *PPCLibBasePTR = NULL;
  108.  
  109. int main(int argc, char *argv[])
  110. {
  111.     int i;
  112.     int processor = 0, debugflag = 0, keep_video = 0, apus_boot = 0;
  113.     u_int baud = 0;
  114.     const char *kernel_name = NULL;
  115.     const char *ramdisk_name = NULL;
  116.     char commandline[CL_SIZE] = "";
  117.  
  118.     ProgramName = argv[0];
  119.     while (--argc) {
  120.     argv++;
  121.     if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help"))
  122.         Usage();
  123.     else if (!strcmp(argv[0], "-k") || !strcmp(argv[0], "--kernel"))
  124.         if (--argc && !kernel_name) {
  125.         kernel_name = argv[1];
  126.         argv++;
  127.         } else
  128.         Usage();
  129.     else if (!strcmp(argv[0], "-r") || !strcmp(argv[0], "--ramdisk"))
  130.         if (--argc && !ramdisk_name) {
  131.         ramdisk_name = argv[1];
  132.         argv++;
  133.         } else
  134.         Usage();
  135.     else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--debug"))
  136.         debugflag = 1;
  137.     else if (!strcmp(argv[0], "-b") || !strcmp(argv[0], "--baud"))
  138.         if (--argc && !baud) {
  139.         baud = atoi(argv[1]);
  140.         argv++;
  141.         } else
  142.         Usage();
  143.     else if (!strcmp(argv[0], "-m") || !strcmp(argv[0], "--memfile"))
  144.         if (--argc && !memfile_name) {
  145.         memfile_name = argv[1];
  146.         argv++;
  147.         } else
  148.         Usage();
  149.     else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--keep-video"))
  150.         keep_video = 1;
  151.     else if (!strcmp(argv[0], "-t") || !strcmp(argv[0], "--model"))
  152.         if (--argc && !model) {
  153.         model = atoi(argv[1]);
  154.         argv++;
  155.         } else
  156.         Usage();
  157.     else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--processor"))
  158.         if (--argc && !processor) {
  159.         processor = atoi(argv[1]);
  160.         argv++;
  161.         } else
  162.         Usage();
  163.     else if (!strcmp(argv[0], "--apus"))
  164.         apus_boot = 1;
  165.     else
  166.         break;
  167.     }
  168.     if (!kernel_name)
  169.     kernel_name = "vmlinux";
  170.  
  171.     SysBase = *(struct ExecBase **)4;
  172.  
  173.     if (apus_boot) {
  174.       if (!(PPCLibBasePTR = (struct PPCLibBase *) 
  175.           OpenLibrary("ppc.library", 37))){
  176.               fprintf(stderr, "Cannot open ppc.library\n");
  177.               return (FALSE);
  178.           }
  179.     }
  180.  
  181.     /*
  182.      *    Join command line options
  183.      */
  184.     i = 0;
  185.     while (argc--) {
  186.     if ((i+strlen(*argv)+1) < CL_SIZE) {
  187.         i += strlen(*argv) + 1;
  188.         if (commandline[0])
  189.         strcat(commandline, " ");
  190.         strcat(commandline, *argv++);
  191.     }
  192.     }
  193.  
  194.     memset(&args.bi, 0, sizeof(args.bi));
  195.     if (processor) {
  196.     int cpu = processor/100%10;
  197.     int fpu = processor/10%10;
  198.     int mmu = processor%10;
  199.     if (cpu)
  200.         args.bi.cputype = 1<<(cpu-1);
  201.     if (fpu)
  202.         args.bi.fputype = 1<<(fpu-1);
  203.     if (mmu)
  204.         args.bi.mmutype = 1<<(mmu-1);
  205.     }
  206.     /*
  207.      *    If we have a memory file, read the memory information from it
  208.      */
  209.     if (memfile_name) {
  210.     FILE *fp;
  211.     int i;
  212.  
  213.     if ((fp = fopen(memfile_name, "r")) == NULL) {
  214.         perror("open memory file");
  215.         fprintf(stderr, "Cannot open memory file %s\n", memfile_name);
  216.         return(FALSE);
  217.     }
  218.  
  219.     if (fscanf(fp, "%lu", &args.bi.chip_size) != 1) {
  220.         fprintf(stderr, "memory file does not contain chip memory size\n");
  221.         fclose(fp);
  222.         return(FALSE);
  223.     }
  224.  
  225.     for (i = 0; i < NUM_MEMINFO; i++)
  226.         if (fscanf(fp, "%lx %lu", &args.bi.memory[i].addr,
  227.                &args.bi.memory[i].size) != 2)
  228.         break;
  229.  
  230.     fclose(fp);
  231.     args.bi.num_memory = i;
  232.     }
  233.     strncpy(args.bi.command_line, commandline, CL_SIZE);
  234.     args.bi.command_line[CL_SIZE-1] = '\0';
  235.     if (model != AMI_UNKNOWN)
  236.     args.bi.model = model;
  237.     args.bi.apus_boot = apus_boot;
  238.  
  239.     args.kernelname = kernel_name;
  240.     args.ramdiskname = ramdisk_name;
  241.     args.debugflag = debugflag;
  242.     args.keep_video = keep_video;
  243.     args.reset_boards = 1;
  244.     args.baud = baud;
  245.     args.puts = Puts;
  246.     args.getchar = GetChar;
  247.     args.putchar = PutChar;
  248.     args.printf = Printf;
  249.     args.open = Open;
  250.     args.seek = Seek;
  251.     args.read = Read;
  252.     args.close = Close;
  253.     args.filesize = FileSize;
  254.     args.sleep = Sleep;
  255.  
  256.     /* Do The Right Stuff */
  257.     linuxboot(&args);
  258.  
  259.     /* if we ever get here, something went wrong */
  260.     exit(EXIT_FAILURE);
  261. }
  262.  
  263.  
  264.     /*
  265.      *  Routines needed by linuxboot
  266.      */
  267.  
  268. static void Puts(const char *str)
  269. {
  270.     fputs(str, stderr);
  271.     fflush(stderr);
  272. }
  273.  
  274. static long GetChar(void)
  275. {
  276.     return(getchar());
  277. }
  278.  
  279. static void PutChar(char c)
  280. {
  281.     fputc(c, stderr);
  282.     fflush(stderr);
  283. }
  284.  
  285. static void Printf(const char *fmt, ...)
  286. {
  287.     va_list args;
  288.  
  289.     va_start(args, fmt);
  290.     vfprintf(stderr, fmt, args);
  291.     va_end(args);
  292.     fflush(stderr);
  293. }
  294.  
  295. static int Open(const char *path)
  296. {
  297.     return(open(path, O_RDONLY));
  298. }
  299.  
  300. static int Seek(int fd, int offset)
  301. {
  302.     return(lseek(fd, offset, SEEK_SET));
  303. }
  304.  
  305.  
  306. static int Read(int fd, char *buf, int count)
  307. {
  308.     return(read(fd, buf, count));
  309. }
  310.  
  311. static void Close(int fd)
  312. {
  313.     close(fd);
  314. }
  315.  
  316. static int FileSize(const char *path)
  317. {
  318.     int fd, size = -1;
  319.  
  320.     if ((fd = open(path, O_RDONLY)) != -1) {
  321.     size = lseek(fd, 0, SEEK_END);
  322.     close(fd);
  323.     }
  324.     return(size);
  325. }
  326.  
  327. static void Sleep(u_long micros)
  328. {
  329.     struct MsgPort *TimerPort;
  330.     struct timerequest *TimerRequest;
  331.  
  332.     if ((TimerPort = CreateMsgPort())) {
  333.     if ((TimerRequest = CreateIORequest(TimerPort,
  334.                         sizeof(struct timerequest)))) {
  335.         if (!OpenDevice("timer.device", UNIT_VBLANK,
  336.                 (struct IORequest *)TimerRequest, 0)) {
  337.         TimerRequest->io_Command = TR_ADDREQUEST;
  338.         TimerRequest->io_Flags = IOF_QUICK;
  339.         TimerRequest->tv_secs = micros/1000000;
  340.         TimerRequest->tv_micro = micros%1000000;
  341.         DoIO((struct IORequest *)TimerRequest);
  342.         CloseDevice((struct IORequest *)TimerRequest);
  343.         }
  344.         DeleteIORequest(TimerRequest);
  345.     }
  346.     DeleteMsgPort(TimerPort);
  347.     }
  348. }
  349.